package com.线程和进程.生产者和消费者;
/*public class IllegalMonitorStateException extends RuntimeException
抛出以表示线程已尝试在对象的监视器上等待或通知其他线程等待对象的监视器，而不拥有指定的监视器。
监视器即锁对象，需要在同步方法里使用才不会抛出异常*/

public class Box {
    //定义一个成员变量，表示第x瓶奶
    private int milk;
    //定义一个成员变量，表示奶箱的状态
    private boolean state = false;

    /*---生产者模式---*/
    //提供存储牛奶和获取牛奶的操作
    public synchronized void put(int milk) {
        //有牛奶就等待消费者消费
        if(state){
            /*void wait() 导致当前线程等待，直到
            另一个线程调用该对象的 notify()方法或 notifyAll()方法 */
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //没有牛奶时生产牛奶
        this.milk = milk;
        System.out.println("送奶工将第" + this.milk + "瓶奶放到奶箱");
        //生产完毕改变状态
        state = true;

        //唤醒其他等待线程
        /*void notifyAll() 唤醒正在等待对象监视器的所有线程*/
        notifyAll();

        addTime();
    }

    /*---消费者模式---*/
    public synchronized void get() {

        //没有牛奶就等待生产
        if(!state){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //有牛奶就消费牛奶
        System.out.println("用户拿到第" + this.milk + "瓶奶");
        //消费完毕改变状态
        state=false;

        //唤醒其他等待线程
        /*void notifyAll() 唤醒正在等待对象监视器的所有线程*/
        notifyAll();

        addTime();

    }

    //延时器
    public static void addTime(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
